package com.dify.knowledge.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dify.knowledge.entity.ManualAnswer;
import com.dify.knowledge.entity.QuestionRecord;
import com.dify.knowledge.entity.UnansweredQuestion;
import com.dify.knowledge.repository.ManualAnswerMapper;
import com.dify.knowledge.repository.QuestionRecordMapper;
import com.dify.knowledge.repository.UnansweredQuestionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 定时任务服务
 */
@Slf4j
@Service
public class ScheduledTaskService {

    private final UnansweredQuestionMapper unansweredQuestionMapper;
    private final ManualAnswerMapper manualAnswerMapper;
    private final QuestionRecordMapper questionRecordMapper;
    private final DifyService difyService;

    public ScheduledTaskService(UnansweredQuestionMapper unansweredQuestionMapper,
                                 ManualAnswerMapper manualAnswerMapper,
                                 QuestionRecordMapper questionRecordMapper,
                                 DifyService difyService) {
        this.unansweredQuestionMapper = unansweredQuestionMapper;
        this.manualAnswerMapper = manualAnswerMapper;
        this.questionRecordMapper = questionRecordMapper;
        this.difyService = difyService;
    }

    /**
     * 定时任务：将高分答案同步到Dify知识库
     * 每天凌晨2点执行
     */
    @Scheduled(cron = "${scheduled.sync-answers.cron:0 0 2 * * ?}")
    public void scheduledSyncTopAnswersToKnowledgeBase() {
        syncTopAnswersToKnowledgeBase();
    }
    
    /**
     * 手动触发：将高分答案同步到Dify知识库
     * 可以通过API手动调用
     */
    @Transactional
    public SyncResult syncTopAnswersToKnowledgeBase() {
        log.info("开始执行定时任务：同步高分答案到Dify知识库");
        
        try {
            // 查询所有待解答的问题
            QueryWrapper<UnansweredQuestion> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", "PENDING");
            List<UnansweredQuestion> pendingQuestions = unansweredQuestionMapper.selectList(queryWrapper);
            
            log.info("找到 {} 个待解答问题", pendingQuestions.size());
            
            int syncedCount = 0;
            int failedCount = 0;
            
            for (UnansweredQuestion question : pendingQuestions) {
                try {
                    // 获取该问题的最高分答案
                    ManualAnswer topAnswer = manualAnswerMapper.selectTopRatedByQuestionId(question.getId());
                    
                    if (topAnswer == null) {
                        log.debug("问题 {} 暂无人工解答，跳过", question.getId());
                        continue;
                    }
                    
                    // 检查是否已经同步过
                    if (Boolean.TRUE.equals(topAnswer.getSyncedToDify())) {
                        log.debug("问题 {} 的最高分答案已同步，跳过", question.getId());
                        continue;
                    }
                    
                    // 检查评分是否足够（至少有1个有用评分，且有用数大于无用数）
                    if (topAnswer.getUsefulCount() == null || topAnswer.getUsefulCount() < 1) {
                        log.debug("问题 {} 的最高分答案评分不足，跳过", question.getId());
                        continue;
                    }
                    
                    if (topAnswer.getUselessCount() != null && 
                        topAnswer.getUsefulCount() <= topAnswer.getUselessCount()) {
                        log.debug("问题 {} 的最高分答案评分不够高，跳过", question.getId());
                        continue;
                    }
                    
                    // 获取原始问题内容
                    QuestionRecord questionRecord = questionRecordMapper.selectById(question.getQuestionRecordId());
                    if (questionRecord == null) {
                        log.warn("找不到问题记录 {}，跳过", question.getQuestionRecordId());
                        continue;
                    }
                    
                    // 构建知识库文档内容：问题 + 答案
                    String documentContent = String.format(
                        "问题：%s\n\n答案：%s\n\n（来源：用户贡献，评分：%d有用/%d无用）",
                        questionRecord.getQuestion(),
                        topAnswer.getAnswer(),
                        topAnswer.getUsefulCount(),
                        topAnswer.getUselessCount()
                    );
                    
                    String fileName = String.format("QA_%d_%s", 
                        question.getId(), 
                        LocalDateTime.now().toString().replace(":", "-"));
                    
                    // 上传到Dify知识库
                    log.info("上传问题 {} 的答案到Dify知识库", question.getId());
                    String difyDocumentId = difyService.uploadDocument(documentContent, fileName);
                    
                    // 更新答案的同步状态
                    topAnswer.setSyncedToDify(true);
                    manualAnswerMapper.updateById(topAnswer);
                    
                    // 更新问题状态为已解答
                    question.setStatus("RESOLVED");
                    question.setResolvedAt(LocalDateTime.now());
                    unansweredQuestionMapper.updateById(question);
                    
                    log.info("问题 {} 的答案已成功同步到Dify，文档ID：{}", question.getId(), difyDocumentId);
                    syncedCount++;
                    
                } catch (Exception e) {
                    log.error("同步问题 {} 的答案失败", question.getId(), e);
                    failedCount++;
                }
            }
            
            log.info("同步任务执行完成，成功同步：{}，失败：{}", syncedCount, failedCount);
            
            return new SyncResult(syncedCount, failedCount, pendingQuestions.size());
            
        } catch (Exception e) {
            log.error("同步任务执行异常", e);
            throw new RuntimeException("同步高分答案到知识库失败：" + e.getMessage(), e);
        }
    }
    
    /**
     * 同步结果
     */
    public static class SyncResult {
        private final int syncedCount;
        private final int failedCount;
        private final int totalCount;
        
        public SyncResult(int syncedCount, int failedCount, int totalCount) {
            this.syncedCount = syncedCount;
            this.failedCount = failedCount;
            this.totalCount = totalCount;
        }
        
        public int getSyncedCount() {
            return syncedCount;
        }
        
        public int getFailedCount() {
            return failedCount;
        }
        
        public int getTotalCount() {
            return totalCount;
        }
    }
}
